package com.xnyzc.lhy.resource.service.impl.jpush;

import com.alibaba.fastjson.JSONObject;
import com.xnyzc.lhy.common.exception.PangException;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.util.IDUtil;
import com.xnyzc.lhy.common.util.TokenUtil;
import com.xnyzc.lhy.resource.config.JPushConfigKey;
import com.xnyzc.lhy.resource.entity.jpush.BizResult;
import com.xnyzc.lhy.resource.entity.jpush.CidEntity;
import com.xnyzc.lhy.resource.entity.jpush.JiGuangErrorEntity;
import com.xnyzc.lhy.resource.entity.jpush.MessageEntity;
import com.xnyzc.lhy.resource.entity.jpush.PushMsgEntity;
import com.xnyzc.lhy.resource.entity.jpush.PushMsgResEntity;
import com.xnyzc.lhy.resource.entity.jpush.ResultCode;
import com.xnyzc.lhy.resource.entity.jpush.SendReportEntity;
import com.xnyzc.lhy.resource.mapper.jpush.ConfigMapper;
import com.xnyzc.lhy.resource.mapper.jpush.MessageMapper;
import com.xnyzc.lhy.resource.service.jpush.MessageService;
import com.xnyzc.lhy.resource.util.CodeUtils;
import com.xnyzc.lhy.resource.util.CsbcHttpResponse;
import com.xnyzc.lhy.resource.util.HttpClientService;
import com.xnyzc.lhy.resource.util.JacksonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;


/**
 * <p>
 * 极光推送
 * </p>
 *
 * @author liuju
 * @since 2019-09-20
 */
@Slf4j
@Service
public class MessageServiceImpl implements MessageService {

    @Resource
    private ConfigMapper configMapper;
    @Resource
    private MessageMapper messageMapper;

    @Resource
    private HttpClientService httpClientService;


    @Value("${global.jPush.apnsProduction}")
    private Boolean apnsProduction;

    /**
     * 进行推送
     *
     * @param messageEntity
     * @return
     */
    @Override
    public BizResult sendMessage(MessageEntity messageEntity, String clientId, String tag) {
        Map<String, String> seachMap = new HashMap<>(16);
        seachMap.put("key", JPushConfigKey.MESSAGE_SERVICE_URL);
        seachMap.put("tag", tag);
        String sendUrl = configMapper.getConfigValue(seachMap);
        Map<String, String> resultMap = new HashMap<>(16);
        if (StringUtils.isEmpty(sendUrl)) {
            log.info("发送消息请求地址不存在");
            resultMap.put("code", "32001");
            resultMap.put("msg", "发送消息请求地址不存在");
            return BizResult.failure(ResultCode.MSG_QUESTIONED_EXIST, resultMap);
        }
        seachMap.put("key", JPushConfigKey.CIDGET_SERVICE_URL);
        String cidUrl = configMapper.getConfigValue(seachMap);
        if (StringUtils.isEmpty(cidUrl)) {
            log.info("获取cid请求地址不存在");
            resultMap.put("code", "32002");
            resultMap.put("msg", "获取cid请求地址不存在");
            return BizResult.failure(ResultCode.MSG_QUESTIONED_EXIST, resultMap);
        }
        String platFrom = "all";
        if (!StringUtils.isEmpty(messageEntity.getPlatFrom())) {
            platFrom = messageEntity.getPlatFrom();
        }
        boolean registrationIdFlag = false;
        if (messageEntity.getRegistrationId() == null || messageEntity.getRegistrationId().size() == 0) {
            registrationIdFlag = true;
        }
        boolean aliasFlag = false;
        if (messageEntity.getAlias() == null || messageEntity.getAlias().size() == 0) {
            aliasFlag = true;
        }
        CsbcHttpResponse resp;
        JiGuangErrorEntity jiGuangErrorEntity = new JiGuangErrorEntity();
        try {
            List<Map<String, String>> headList = httpHeadList(messageEntity.getAppKey(), messageEntity.getMasterSecret());
            resp = httpClientService.get(cidUrl, headList, null, null);
            CidEntity cidInfo = new CidEntity();
            int httpCode = 200;
            if (httpCode == resp.getRespStatusCode() && !StringUtils.isEmpty(resp.getRespBodyCont())) {
                cidInfo = JacksonUtils.fromJsonRuntimeException(resp.getRespBodyCont(), CidEntity.class);
            } else {
                log.info("请求cid错误，未获取cid");
                if (StringUtils.isEmpty(resp.getRespBodyCont())) {
                    log.info("消息平台返回应答为空");
                    resultMap.put("code", "32003");
                    resultMap.put("msg", "消息平台返回应答为空");
                    return BizResult.failure(ResultCode.MSG_QUESTIONED_EXIST, resultMap);
                }
                log.info("消息平台返回应答：" + resp.getRespBodyCont());
                jiGuangErrorEntity = JacksonUtils.fromJsonRuntimeException(resp.getRespBodyCont(), JiGuangErrorEntity.class);
                resultMap.put("code", jiGuangErrorEntity.getError().getCode());
                resultMap.put("msg", jiGuangErrorEntity.getError().getMessage());
                return BizResult.failure(ResultCode.MSG_QUESTIONED_EXIST, resultMap);
            }
            PushMsgEntity pushMsgEntity = null;
            PushMsgResEntity pushMsgResEntity = null;
            if (registrationIdFlag && aliasFlag) {
                pushMsgEntity = new PushMsgEntity();
                pushMsgEntity.setCid(cidInfo.getCidlist().get(0));
                pushMsgEntity.setPlatform(platFrom);
                // 设置ios推送环境
                JSONObject optionsJSON = new JSONObject();
                optionsJSON.put("apns_production", apnsProduction);
                pushMsgEntity.setOptions(optionsJSON);
            } else {
                pushMsgResEntity = new PushMsgResEntity();
                pushMsgResEntity.setCid(cidInfo.getCidlist().get(0));
                pushMsgResEntity.setPlatform(platFrom);
                // 设置ios推送环境
                JSONObject optionsJSON = new JSONObject();
                optionsJSON.put("apns_production", apnsProduction);
                pushMsgResEntity.setOptions(optionsJSON);

            }
            if (registrationIdFlag && aliasFlag) {
                pushMsgEntity.setAudience("all");
            } else {
                if (!registrationIdFlag) {
                    Map<String, List<String>> reg = new HashMap<>(16);
                    reg.put("registration_id", messageEntity.getRegistrationId());
                    pushMsgResEntity.setAudience(reg);
                } else if (!aliasFlag) {
                    Map<String, List<String>> reg = new HashMap<>(16);
                    reg.put("alias", messageEntity.getAlias());
                    pushMsgResEntity.setAudience(reg);
                }
            }
            // 设置通知或消息信息(重点部分)
            notifityAndMessageInfo(messageEntity, registrationIdFlag, aliasFlag, pushMsgEntity, pushMsgResEntity);

            SendReportEntity sendReportEntity = new SendReportEntity();
            String pushMsgStr = "";
            if (registrationIdFlag && aliasFlag) {
                pushMsgStr = JacksonUtils.toJsonRuntimeException(pushMsgEntity);
            } else {
                pushMsgStr = JacksonUtils.toJsonRuntimeException(pushMsgResEntity);
            }
            resp = httpClientService.post(sendUrl, headList, pushMsgStr);

            if (httpCode == resp.getRespStatusCode() && !StringUtils.isEmpty(resp.getRespBodyCont())) {
                //sendReportEntity = JacksonUtils.fromJsonRuntimeException(resp.getRespBodyCont(), SendReportEntity.class);
                // 保存推送日志
                if (registrationIdFlag && aliasFlag) {
                    this.insertExe(pushMsgEntity, messageEntity, clientId, tag, messageEntity.getAlias());
                } else {
                    this.insertExe(pushMsgResEntity, messageEntity, clientId, tag, messageEntity.getAlias());
                }
            } else {
                log.info("请求推送消息错误，未成功推送");
                if (StringUtils.isEmpty(resp.getRespBodyCont())) {
                    log.info("消息平台返回应答为空");
                    resultMap.put("code", "32004");
                    resultMap.put("msg", "消息平台返回应答为空");
                    return BizResult.failure(ResultCode.MSG_QUESTIONED_EXIST, resultMap);
                }
                log.info("消息平台返回应答：" + resp.getRespBodyCont());
                jiGuangErrorEntity = JacksonUtils.fromJsonRuntimeException(resp.getRespBodyCont(), JiGuangErrorEntity.class);
                resultMap.put("code", jiGuangErrorEntity.getError().getCode());
                resultMap.put("msg", jiGuangErrorEntity.getError().getMessage());
                return BizResult.failure(ResultCode.MSG_QUESTIONED_EXIST, resultMap);
            }
        } catch (Exception e) {
            log.info("", e);
            resultMap.put("code", "99999");
            resultMap.put("msg", "发生未知异常");
            return BizResult.failure(ResultCode.MSG_QUESTIONED_EXIST, resultMap);
        }
        return BizResult.success();
    }

    /**
     * 设置通知或消息信息
     *
     * @param messageEntity
     * @param registrationIdFlag
     * @param aliasFlag
     * @param pushMsgEntity
     * @param pushMsgResEntity
     */
    private void notifityAndMessageInfo(MessageEntity messageEntity, boolean registrationIdFlag, boolean aliasFlag, PushMsgEntity pushMsgEntity, PushMsgResEntity pushMsgResEntity) {
        // 通知类型
        if (Objects.equals(messageEntity.getJPushType(), 0)) {
            JSONObject notificationJson = new JSONObject();

            MessageEntity androidMessage = new MessageEntity();
            androidMessage.setAlert(messageEntity.getMsg_content());
            androidMessage.setTitle(messageEntity.getTitle());
            androidMessage.setExtras(messageEntity.getExtras());
            notificationJson.put("android", androidMessage);

            MessageEntity iosMessage = new MessageEntity();
            iosMessage.setAlert(messageEntity.getMsg_content());
            iosMessage.setSound(messageEntity.getSound());
            iosMessage.setExtras(messageEntity.getExtras());
            notificationJson.put("ios", iosMessage);

            if (registrationIdFlag && aliasFlag) {
                pushMsgEntity.setNotification(notificationJson);
            } else {
                pushMsgResEntity.setNotification(notificationJson);
            }
        }
        // 自定义消息推送信息
        else if (Objects.equals(messageEntity.getJPushType(), 1)) {
            MessageEntity pushMessage = new MessageEntity();
            pushMessage.setMsg_content(messageEntity.getMsg_content());
            pushMessage.setTitle(messageEntity.getTitle());
            pushMessage.setExtras(messageEntity.getExtras());
            if (registrationIdFlag && aliasFlag) {
                pushMsgEntity.setMessage(pushMessage);
            } else {
                pushMsgResEntity.setMessage(pushMessage);
            }
        } else {
            throw new PangException(EErrorCode.jPushSendType);
        }
    }

    private void insertExe(PushMsgEntity pushMsgEntity, MessageEntity bodyString, String clientId, String tag, List<String> aliasFlag) {
        insertMessageInfo(bodyString, clientId, pushMsgEntity.getPlatform(), tag, aliasFlag);
    }

    private void insertMessageInfo(MessageEntity bodyString, String clientId, String platform, String tag, List<String> aliasFlag) {
        Date date = new Date();
        for(String alias:aliasFlag){
            Long id = IDUtil.nextId();
            Map<String, Object> insertMap = new HashMap<>(16);
            insertMap.put("record_id", id);
            insertMap.put("app_key", bodyString.getAppKey());
            insertMap.put("plat_from", platform);
            insertMap.put("msg_content", bodyString.getMsg_content());
            insertMap.put("title", bodyString.getTitle());
            insertMap.put("registration_id", JacksonUtils.toJsonRuntimeException(bodyString.getRegistrationId()));
            insertMap.put("tag", tag);
            insertMap.put("create_user", id);
            insertMap.put("create_time", date);
            insertMap.put("update_user", id);
            insertMap.put("update_time", date);
            insertMap.put("client_id", clientId);
            insertMap.put("alias_flag", alias);
            messageMapper.insertRecod(insertMap);
        }
    }

    private void insertExe(PushMsgResEntity pushMsgResEntity, MessageEntity bodyString, String clientId, String tag, List aliasFlag) {
        insertMessageInfo(bodyString, clientId, pushMsgResEntity.getPlatform(), tag, aliasFlag);
    }

    private List<Map<String, String>> httpHeadList(String appKey, String masterSecret) {
        Map<String, String> headCleMap = new HashMap<>(16);
        List<Map<String, String>> headList = new ArrayList<>();
        headCleMap.put("Authorization", CodeUtils.getBasicAuthorization(appKey, masterSecret));
        headList.add(headCleMap);
        return headList;
    }


}
